//
//  StatusListViewModle.swift
//  上海微博
//
//  Created by co on 16/3/5.
//  Copyright © 2016年 王南侠. All rights reserved.
//

import Foundation
import SDWebImage

/// 微博视图模型 - 负责加载【网络 / 本地数据缓存】 的数据
/// 视图模型 只管理逻辑和数据，不负责和UI打交道！

class StatusListViewModle {
    
    /// 微博视图模型数组
    lazy var statusList = [StatusViewModle]()
    
    /// 清理王数据 - 在接受到内存警告时候调用
    func cleanup() {
        statusList.removeAll()   
    }
    
    /**
     重构方法的步骤
     
     1.新建方法
     2.将要抽取的代码负责到新的方法中
     3.检查参数，以及代码的逻辑
     */
     /**
     加载微博数据
     
     - parameter isPullip: 是否上拉刷新
     - parameter finshed:  完成回调（是否成功）
     */
    func loadDataStatus(isPullip: Bool,finshed: (isSuccessed: Bool)->()) {
        
        // 下拉刷新索引
        let since_id = isPullip ? 0: (statusList.first?.status.id ?? 0)
        
        // 上拉刷新索引
        let max_id = (!isPullip ? 0: statusList.last?.status.id ?? 0)
        
        // 加载微博数据
        NetworkTools.sharedTools.loadStatus(since_id, max_id: max_id) { (result) -> () in
            
            guard let array = result?["statuses"] as? [[String: AnyObject]] else {
                print("您的网络不给力")
                finshed (isSuccessed: false)
                return
            }
            
            //  遍历数组 字典转模型
            // 提示，在实际开发中，如果下列代码性能不好，也可以放在异步执行
            var arrayM = [StatusViewModle]()
            for dict in array {
                arrayM.append(StatusViewModle(status: Status.yy_modelWithJSON(dict)!))
                
            }
            print("本次数据刷新条数 \(arrayM.count)")
            
            // 如果是上拉刷新放到后面
            if max_id > 0 {
                self.statusList += arrayM
            } else {
                self.statusList = arrayM + self.statusList
            }
            
            // 缓存单张图片 玩成之后，在执行成功回调
           self.cacheSingleWebimage(arrayM,finished: finshed)

        }
    }
    
    
    /// 缓存网络单张图片
    ///  - parameter array：本次网络请求获得的微博视图模型数据
    /// 应该在缓存单张图片完成/ 更新视图模型中的配图视图的大小 / 完成回调刷新表格
    /// 所有的图像框架，下载图像之前都会检查本地缓存，如果本地缓存已经存在 ，不会再次下载
    private func cacheSingleWebimage(array: [StatusViewModle],finished: (isSuccessed: Bool)->()) {
        
        // 1> 创建调度组
        let  group = dispatch_group_create()
        // 数据长度
        var dataLength = 0
        // 遍历数组 判断原创微博 转发微博是否为单张图 如果是单张图片就需要缓存
        // 只有单张图片需要按照等比例显示
        for viewModle in array {
            
            // 判断微博配图数量
            if viewModle.picturesURls?.count != 1 {
                continue
            }
            
            // 2.一定是单张图片，
            guard let urlString = viewModle.picturesURls?[0].thumbnail_pic, url = NSURL(string: urlString) else {
                continue
            }
            print(viewModle.picturesURls)
            
            // 3.下载图像 ,调用框架核心函数
            // 2> 入组
            dispatch_group_enter(group)
            // 无论本地是否有缓存，都会返回图像
            SDWebImageManager.sharedManager().downloadImageWithURL(url, options: [],
                progress: nil,
                completed: { (image, _, _, _, _) -> Void in
                    
                    // 判断是否下载成功
                    if let image = image, data = UIImagePNGRepresentation(image){
                        // 累加数据长度 提示 - 一定要要有办法计算缓存的数据长度 既是本地缓存存在 ，回调方法同样也会被调用
                        dataLength += data.length
                        
                        // 更新模型对应的配图的视图大小
                        viewModle.updateSingleImagePitureViewSize()
                        
                    }
                    
                    // 3> 出组
                    dispatch_group_leave(group)
            })
        }
        
        // 4 监听下载完成 完成代码在异步执行
        dispatch_group_notify(group,dispatch_get_global_queue(0, 0)) { () -> Void in
            // dataLength 中很有可能已经包含了本地缓存图像的大小
            print("单张图片缓存完成 \(dataLength / 1024) K \(NSThread.currentThread())")
            
            // 计算本次加载数据视图模型对应的行高
            for viewModle in array {
                viewModle.calcRowHeight()
            }
            
            //  主队列执行完成回调
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                finished(isSuccessed: true)
                
            })
            
        }
    }
}